from django.db import transaction
from rest_framework.serializers import ModelSerializer
from rest_framework import serializers

from goods.models import SKU, GoodsCategory, Goods, SpecificationOption, GoodsSpecification, SKUSpecification, \
    GoodsVisitCount


class SKUSerializer(ModelSerializer):
    class Meta:
        model = SKU
        fields = '__all__'


class GoodsCategorySerializer(ModelSerializer):
    class Meta:
        model = GoodsCategory
        fields = ('id', 'name')


class SPUSerializer(ModelSerializer):
    class Meta:
        model = Goods
        fields = ('id', 'name')


class GoodsOptineSerializer(ModelSerializer):
    class Meta:
        model = SpecificationOption
        fields = ('id', 'value')


class GoodsSpecSerializer(ModelSerializer):
    goods = serializers.StringRelatedField(read_only=True)
    goods_id = serializers.IntegerField(read_only=True)

    options = GoodsOptineSerializer(read_only=True, many=True)

    class Meta:
        model = GoodsSpecification

        fields = '__all__'


class SKUSpecificationSerializer(ModelSerializer):
    spec_id = serializers.IntegerField()
    option_id = serializers.IntegerField()

    class Meta:
        model = SKUSpecification
        fields = ('spec_id', 'option_id')


class SKUKeepSerializer(ModelSerializer):
    spu_id = serializers.IntegerField()
    category_id = serializers.IntegerField()

    spu = serializers.StringRelatedField(read_only=True)
    category = serializers.StringRelatedField(read_only=True)
    specs = SKUSpecificationSerializer(many=True)

    class Meta:
        model = SKU
        fields = '__all__'

    def create(self, validated_data):
        specs_data = validated_data.pop('specs')
        save_id = transaction.savepoint()

        sku = SKU.objects.create(**validated_data)

        for spec_data in specs_data:
            SKUSpecification.objects.create(sku=sku, **spec_data)
        transaction.savepoint_commit(save_id)
        return sku

    def update(self, instance, validated_data):

        specs_data = validated_data.pop('specs')
        save_id = transaction.savepoint()

        super().update(instance, validated_data)

        for spec_data in specs_data:
            SKUSpecification.objects.filter(sku=instance, spec_id=spec_data.get("spec_id")).update(
                option_id=spec_data.get("option_id"))
        transaction.savepoint_commit(save_id)
        return instance


class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = GoodsCategory
        fields = ('id', 'name')


class GoodsVisitCountSerialize(serializers.ModelSerializer):
    category = serializers.StringRelatedField()

    class Meta:
        model = GoodsVisitCount

        fields = ('category', 'count')
